package com.zhny.spraygun.rtu.plugin;

import com.google.common.collect.ImmutableMap;
import com.zhny.aiot.plugin.ICenterFacilities;
import com.zhny.aiot.plugin.IDeviceFactory;
import com.zhny.aiot.plugin.core.model.IRequestMessage;
import com.zhny.aiot.plugin.core.utils.MessageUtils;
import com.zhny.aiot.plugin.modbus.ModemEngine;
import com.zhny.aiot.plugin.modbus.device.ModemConfig;
import com.zhny.aiot.plugin.modbus.device.ModemDevice;
import com.zhny.aiot.plugin.modbus.device.modbus.ModbusCommandParam;
import com.zhny.aiot.plugin.modbus.handler.model.ModemRequestMessage;
import com.zhny.aiot.plugin.modbus.handler.model.ModemResponseMessage;
import com.zhny.aiot.plugin.model.DeviceEntity;
import com.zhny.aiot.plugin.model.MessageEntry;
import com.zhny.aiot.plugin.model.MessageType;
import com.zhny.aiot.plugin.model.TaskEntity;
import com.zhny.spraygun.rtu.plugin.model.SpraygunRTUStoreEntry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;

public class SpraygunRTUDevice extends ModemDevice<SpraygunRTUStoreEntry> {
    private static final Logger logger=LoggerFactory.getLogger (SpraygunRTUDevice.class);
    private final Map<String, ModbusCommandParam> CommandOperations;

    public SpraygunRTUDevice(ModemEngine engine, IDeviceFactory<ModemConfig> factory, ICenterFacilities centerFacilities, DeviceEntity entity) {
        super (engine, factory, centerFacilities, entity);
        CommandOperations=new ImmutableMap.Builder<String, ModbusCommandParam> ()
                .put ("sprayGunOpen", ModbusCommandParam.valueOf ((short) 6, 10, 0x65))
                .put ("sprayGunClose", ModbusCommandParam.valueOf ((short) 6, 10, 0x68))
                .put ("sprayGunQuery", ModbusCommandParam.valueOf ((short) 3, 3, 1))
                .build ();
    }

    @Override
    public void onDecoder(ModemResponseMessage modemResponseMessage) {
        logger.info ("-------zhny spraygun rtu decoder start-------");
        MessageEntry entry=MessageUtils.createMessageEntry (this.getId ());
        entry.setType (MessageType.RESULT);
        SpraygunRTUStoreEntry storeEntry=new SpraygunRTUStoreEntry ();
        int status = modemResponseMessage.getData ().readUnsignedShort ();
        if(modemResponseMessage.getFunction () == 0x06) {
            String value=status == 0x65 ? "开启" :
                    status == 0x68 ? "关闭" : "未知";
            storeEntry.setSprayGunStatus (value);
        }else if(modemResponseMessage.getFunction () == 0x03) {
            String value=status == 0x80 ? "开启" :
                    status == 0x81 ? "关闭" : "未知";
            storeEntry.setSprayGunStatus (value);
        }else {
            storeEntry.setSprayGunStatus ("数据错误");
            entry.setData (storeEntry);
            entry.setType (MessageType.ERROR);
            nofity (entry);
            return;
        }
        logger.info ("-------spraygun rtu：{},值:{}-------", this.getDeviceEntity ().getName (), storeEntry);
        entry.setData (storeEntry);
        nofity (entry);
        saveReal (storeEntry);
        save (storeEntry);
    }

    @Override
    protected IRequestMessage getCommand(TaskEntity taskEntity) {
        logger.info ("-------zhny spraygun rtu encode command !-------");
        MessageEntry entry=MessageUtils.createMessageEntry (this.getId ());
        entry.getProperties ().put ("task_name", taskEntity.getMethodName ());
        entry.setType (MessageType.OPERATION);
        ModbusCommandParam command=CommandOperations.get (taskEntity.getMethodName ());
        if(command == null) {
            entry.setType (MessageType.ERROR);
            entry.setData (String.format ("factory[%s] no support command [%s]", getTypeId (), taskEntity.getMethodName ()));
            this.nofity (entry);
            return null;
        }
        String methodName=taskEntity.getMethodName ();
        logger.info ("-------zhny spraygun rtu {},{} command !-------", this.getDeviceEntity ().getName (), methodName);
        logger.info ("-------zhny spraygun rtu encode a:{}-o:{}-r:{}-d:{}!-------",
                this.getConfig ().getAddress (),
                command.getOper (),
                command.getRegAdress (),
                command.getDataSize ());
        return new ModemRequestMessage (
                Integer.valueOf (this.getConfig ().getAddress ()),
                command.getOper (),
                command.getRegAdress (),
                command.getDataSize ()
        );
    }

    @Override
    protected void disposable() {

    }
}
